package edu.java.ishop.socketserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.List;
import java.util.concurrent.Semaphore;

import org.springframework.beans.factory.annotation.Value;

import edu.java.ishop.dao.ProductDao;
import edu.java.ishop.dao.impl.ProductFileDao;
import edu.java.ishop.model.Product;
import edu.java.ishop.utils.ApplicationConfiguration;

public class ProductSocketServer {

	private static ProductSocketServer instance = new ProductSocketServer();
	public  boolean stopMe = false;
	private ProductSocketServer() {
		// TODO Auto-generated constructor stub
	}
	
	@Value("${socket.port}")
	private int socketPort;
	
	private void start(Semaphore startCallback) throws IOException {
		ProductDao productDao = new ProductFileDao();
		
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		
		//int port = Integer.valueOf(ApplicationConfiguration.getItem("socket.port"));
		int port = Integer.valueOf(socketPort);
		serverSocketChannel.socket().bind(new InetSocketAddress(port));
		serverSocketChannel.configureBlocking(false);
		
		startCallback.release();
		while(!stopMe){
			SocketChannel requestChannel = serverSocketChannel.accept();
			if(requestChannel == null){
				continue;
			}
			Socket requestSocket = requestChannel.socket();
			ObjectOutputStream objectOutputStream = new  ObjectOutputStream(requestSocket.getOutputStream());
			objectOutputStream.flush();
			
			BufferedReader requestReader = new BufferedReader(new InputStreamReader(requestSocket.getInputStream()));
			String command = requestReader.readLine();
			if(command !=null){
				switch (command) {
				case "getAll":
					//send back the list of products
					List<Product> products = productDao.getAll();
					if(products.isEmpty()){
						objectOutputStream.write("No products available".getBytes());
					}else{
						objectOutputStream.writeObject(products);
					}
					
					break;

				default:
					break;
				}
			}
			requestReader.close();
			objectOutputStream.close();
		}
		serverSocketChannel.close();
		stopMe = false;
	}
	public static void launch(Semaphore startCallback) throws IOException {
		instance.start(startCallback);
		
	}
	public static void shutdown() {
		instance.stopMe = true;
		
	}

}
